#pragma once

#include <cstdint>
#include <vector>

#include "cuda.h"
#include "cuda_runtime.h"



	


template<class T>
class IcemVolume {
public:	
	IcemVolume(int* size, T* data, double alpha, double brightness, double contrast, unsigned char colormap[3*256], float mat[4][4]);
	virtual short3* GetSlice(double pos[3], int dir, double minCoord_in[3], bool firstSlice, bool interp); //dir = 0 (z), 1(y) or 2(x)
	virtual void SlicePreparation(double pos[3], int dir, double minCoord_in[3]);
	~IcemVolume();
	double GetAlpha() {return alpha;};
	void GetSliceSize(int dir, int* sizeX, int* sizeY);
	void GetSize(size_t size[3]) {
		for (int i=0;i<3;++i)
			size[i] = volumeSize[i];
	};
	void GetMinCoordinates(double minCoord[3]) {
		for (int i=0;i<3;++i)
			minCoord[i] = minCoordinates[i];
	};
	float GetStep() {return step;};
	float GetContrast(){return contrast;};
	float GetBrightness(){return brightness;};
	void SetSliceSize(size_t size[3]);
	void SetAlpha(float a) {alpha = a;};
	void SetBrightness(float b) {brightness = b;};
	void SetContrast(float c) {contrast = c;};
	void SetColormap(unsigned char cm[3*256]);
	void SetTalairachColormap(unsigned char cm[3*2000]);
    void SetFilterLimits(float lowerLimit, float upperLimit);
    void SetTransformationMatrix(float mat[4][4]);
	void GetRenderedVolume(unsigned char* v, double minCoord_in[3], size_t size[3], bool interp);
protected:
	int shape[3];
	//std::vector<T> volume;
	void* cudaVolume;
	short3 *cudaImage[3];
	float* cudaMat;
	int* cudaI;
	int* cudaJ;
	double minCoordinates[3];
	size_t volumeSize[3];
	int sliceSizeI[3];
	int sliceSizeJ[3];
	float step;
	//__shared__ T* Volume;
	//__shared__ T* cudaImage;
	float transformation[4][4];
	float sliceTransformation[16];
	unsigned char* colormap;
	float alpha;
	float brightness;
	float contrast;
    float2 filterLimits; // filter value inside the limits

};